package com.zhuss.core.processor;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import com.zhuss.bean.bo.core.auth.AuthBo;
import com.zhuss.bean.unit.core.auth.ResourceBean;
import com.zhuss.bean.vo.core.auth.AuthResourceVo;
import com.zhuss.common.AbstractProcessor;
import com.zhuss.common.Processor;
import com.zhuss.core.db.entity.Resource;
import com.zhuss.db.entity.OpLog;
import com.zhuss.enums.LogActionEnum;
import com.zhuss.enums.MoudleEnum;
import com.zhuss.exception.OceanException;
import com.zhuss.util.JsonUtil;

/**
 * 用户的接口权限 processor
 * @Author: zhushanshuo
 * @Date: 2019/12/24 17:55
 */
@Component("authResourceProcessor")
public class AuthResourceProcessor extends AbstractProcessor<AuthResourceVo, AuthBo> implements Processor<AuthResourceVo, AuthBo> {

	
	@Autowired
	@Qualifier("userRoleRead")
	private UserRoleRead userRoleRead;
	
	@Autowired
	@Qualifier("rolePermissionRead")
	private RolePermissionRead rolePermissionRead;
	
	@Autowired
	@Qualifier("permissionResourceRead")
	private PermissionResourceRead permissionResourceRead;
	
	
	@Autowired
	@Qualifier("resourceRead")
	private ResourceRead resourceRead;
	
	@Autowired
	@Qualifier("roleRead")
	private RoleRead roleRead;
	
    /**
     * 校验
     */
    @Override
    public void check(AuthBo bo) throws OceanException {
    	
    }
    
    /**
     * 操作方法
     * @throws OceanException 
     */
	@Override
	@SuppressWarnings("unchecked")
    public AuthResourceVo process(AuthBo bo) throws OceanException {
		List<ResourceBean> list = new ArrayList<>();
    	AuthResourceVo result = new AuthResourceVo();
    	// 查询出当前区域用户的角色
    	List<Long> roleIdList = (List<Long>) userRoleRead.listRoleId(bo.getConcurrentUserId());
    	
    	List<Long> permissionIdList = new ArrayList<Long>();
    	// 查询出当前用户的所有角色所关联的权限
    	if (!roleIdList.isEmpty()) {
    		permissionIdList = (List<Long>) rolePermissionRead.listPermissionId(roleIdList);
    	}
    	
    	List<Long> resourceIdList = new ArrayList<Long>();
    	// 查询出当前用户的所有角色所关联的权限， 然后所关联的所有的接口权限
    	if (!permissionIdList.isEmpty()) {
    		resourceIdList = (List<Long>) permissionResourceRead.listResourceId(permissionIdList);
    	}
    	List<Long> resourceIdListSystem = (List<Long>) resourceRead.listResourceId(bo.getConcurrentSystem());
    	resourceIdList.retainAll(resourceIdListSystem);
    	
    	List<Long> resourceIdListPublic = (List<Long>) resourceRead.listResourcePublic(bo.getConcurrentSystem());
    	resourceIdList.addAll(resourceIdListPublic);
    	fixSame(resourceIdList);
    	List<Resource> resourceList = new ArrayList<Resource>();
    	if (!resourceIdList.isEmpty()) {
    		resourceList = (List<Resource>) resourceRead.listResource(resourceIdList);
    	}
    	transferToResult(resourceList, list);
    	result.setResourceList(list);
        return result;
    }
	
	
    
    private void fixSame(List<Long> resourceIdList) {
		HashSet<Long> set = new HashSet<Long>();
		set.addAll(resourceIdList);
		resourceIdList.clear();
		resourceIdList.addAll(set);
		
	}

	private void transferToResult(List<Resource> resourceList,
			List<ResourceBean> result) {
		for (Resource item : resourceList) {
			ResourceBean rb = new ResourceBean();
			BeanUtils.copyProperties(item, rb);
			result.add(rb);
		}
	}

	/**
     * 操作日志
     */
	@Override
	public AuthResourceVo log(AuthBo param) throws OceanException {
		OpLog record = new OpLog();
    	record.setMoudle(MoudleEnum.基础模块.key());
    	record.setAction(LogActionEnum.用户的接口.key());
    	record.setTargetId(param.getConcurrentUserId());
    	record.setTargetName("用户ID:" + param.getConcurrentUserId() + ", 系统:" + param.getConcurrentSystem());
    	record.setContent("参数: " + JsonUtil.toJson(param));
    	record.setReason(param.getExceptionReason());
    	
    	record.setCreatorId(param.getConcurrentUserId());
    	record.setCreator(param.getConcurrentUserName());
    	record.setCreateTime(new Date());
    	log(record);
    	return null;
	}
}
